package org.soderiakelvy.model.service.imp;

import java.io.Serializable;
import java.util.List;



import org.soderiakelvy.model.dao.ComercializacionPackDao;
import org.soderiakelvy.model.dao.FrioCalorDao;
import org.soderiakelvy.model.dao.PackDao;
import org.soderiakelvy.model.dao.ProductoDao;
import org.soderiakelvy.model.dao.SucursalFrioCalorDao;
import org.soderiakelvy.model.dao.SucursalProductoDao;
import org.soderiakelvy.model.dao.TipoClienteDao;
import org.soderiakelvy.model.dao.TipoProductoDao;
import org.soderiakelvy.model.dao.imp.ComercializacionPackDaoImp;
import org.soderiakelvy.model.dao.imp.FrioCalorDaoImp;
import org.soderiakelvy.model.dao.imp.PackDaoImp;
import org.soderiakelvy.model.dao.imp.ProductoDaoImp;
import org.soderiakelvy.model.dao.imp.SucursalFrioCalorDaoImp;
import org.soderiakelvy.model.dao.imp.SucursalProductoDaoImp;
import org.soderiakelvy.model.dao.imp.TipoClienteDaoImp;
import org.soderiakelvy.model.dao.imp.TipoProductoDaoImp;
import org.soderiakelvy.model.domain.FrioCalorVO;
import org.soderiakelvy.model.domain.PackVO;
import org.soderiakelvy.model.domain.ProductoVO;
import org.soderiakelvy.model.domain.TipoClienteVO;
import org.soderiakelvy.model.domain.SucursalProductoVO;
import org.soderiakelvy.model.domain.TipoProductoVO;
import org.soderiakelvy.model.service.ProductoServicio;
import org.soderiakelvy.model.util.ConstantModel;

public class ProductoServicioImp implements ProductoServicio, Serializable {
	private static final long serialVersionUID = 6863636089414886249L;
	
	ProductoDao productoDao;
	FrioCalorDao frioCalorDao;
	TipoProductoDao tipoProductoDao;
	PackDao packDao;
	ComercializacionPackDao comercializacionPackDao;
	SucursalFrioCalorDao sucursalFrioCalorDao;
	SucursalProductoDao sucProDao;

	
	public ProductoServicioImp(){
		productoDao = new ProductoDaoImp();
		frioCalorDao = new FrioCalorDaoImp();
		tipoProductoDao = new TipoProductoDaoImp();
		packDao = new PackDaoImp();
		comercializacionPackDao = new ComercializacionPackDaoImp();
		sucursalFrioCalorDao = new SucursalFrioCalorDaoImp();
		sucProDao = new SucursalProductoDaoImp();
	}

	//-------- Producto CRUD ---------
	@Override
	public String insertProductoVO(ProductoVO producto) {
		producto.setNombre(producto.getNombre().toUpperCase());
		if(!nombreProductoDuplicado(producto)){
			try {
				productoDao.insertProductoVO(producto);
				return ConstantModel.SUCCESS;
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("Error al guardar un producto "+e.getMessage());
				return ConstantModel.FAILED;
			}
		}else{
			return ConstantModel.NOMBRE_DUPLICADO;
		}
	}
	
	@Override
	public String updateProductoVO(ProductoVO producto) {
		producto.setNombre(producto.getNombre().toUpperCase());
		if(!nombreProductoDuplicado(producto)){
			try {
				productoDao.updateProductoVO(producto);
				return ConstantModel.SUCCESS;
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("Error al modificar un producto "+e.getMessage());
				return ConstantModel.FAILED;
			}
		}else{
			return ConstantModel.NOMBRE_DUPLICADO;
		}
		
	}
	
	private boolean nombreProductoDuplicado(ProductoVO producto){
		boolean result;
		ProductoVO p = productoDao.getProductoByNombre(producto.getNombre());
		if(producto.getProductoId() == null){
			//un control de alta
			if(p !=null){
				result = true;
			}else {
				result = false;
			}
		}else {
			//control de update
			if(p != null){
				//existe un nombre en la BD
				if(p.getProductoId().equals(producto.getProductoId())){
					result = false;
				}else{
					result = true;
				}
			}else{
				result = false;
			}
		}
		return result;
	}
	@Override
	public String deleteProductoVO(ProductoVO producto) {
		if(!productoEstaAsignado(producto)){
			try {
				productoDao.deleteProductoVO(producto);
				return ConstantModel.SUCCESS;
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("Error al eliminar un producto "+e.getMessage());
				return ConstantModel.FAILED;
			}
		}else{
			return ConstantModel.DELETE_ASIGNADO;
		}
		
	}

	private boolean productoEstaAsignado(ProductoVO producto){
		boolean result = false;
		try {
			List<SucursalProductoVO> sucPro = sucProDao.getAllSucursalProductoVO();
			for(SucursalProductoVO sp : sucPro){
				if(sp.getProductoDescuento().getProducto().getProductoId().equals(producto.getProductoId())){
					result = true;
				}
			}
			return result;
		} catch (Exception e) {
			e.printStackTrace();
			result = false;
		}
		return result;
	}
	@Override
	public ProductoVO getProductoById(long productoId) {
		try{
			return productoDao.getProductoVOById(productoId);
		}catch (Exception e){
			e.printStackTrace();
			System.out.println("Error al Obtener un Producto "+ e.getMessage());
			return null;			
		}
	}
	
	
	//------------------METODOS DE FRIO CALOR -------------------------------------------
	@Override
	public String insertFrioCalorVO(FrioCalorVO friocalor) {
		getFrioCalorConMayuscula(friocalor);
		friocalor.setEstado(ConstantModel.ESTADO_FRIO_CALOR.FABRICA.getEstado());
		try {
			frioCalorDao.insertFrioCalorVO(friocalor);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al guardar un Frio Calor "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}
	
	@Override
	public Boolean existeNumeroSerieFrioCalor(String numeroSerie) {
		
		try{
			if (frioCalorDao.getFrioCalorByNumSerie(numeroSerie) != null){
				return true;
			}else
				return false;
		}catch (Exception e){
			e.printStackTrace();
			System.out.println("Error al buscar Numero de Serie de FrioCalor. "+e.getMessage());
			return null;	
		}
	}
	
	@Override
	public String updateFrioCalorVO(FrioCalorVO friocalor) {
		getFrioCalorConMayuscula(friocalor);
		try {
			frioCalorDao.updateFrioCalorVO(friocalor);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al modificar un Frio Calor "+e.getMessage());
			return ConstantModel.FAILED;
		}
	}

	@Override
	public String deleteFrioCalorVO(FrioCalorVO frioCalor) {
		if(!existenSucursalesFrioCalorDeFrioCalor(frioCalor)){
			try {
				frioCalorDao.deleteFrioCalorVO(frioCalor);
				return ConstantModel.SUCCESS;
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("Error al eliminar un FrioCalor. "+e.getMessage());
				return ConstantModel.FAILED;
			}
		}else {
			return ConstantModel.DELETE_ASIGNADO;
		}	
	}
	
	
	private boolean existenSucursalesFrioCalorDeFrioCalor(FrioCalorVO fc){
		if(sucursalFrioCalorDao.getSucursalFrioCalorByFrioCalor(fc).isEmpty()){
			System.out.println(" NO HAY Frio Calor asignados");
			return false;
		}else {
			System.out.println(" SI  HAY frio Calor asignados");
			return true;
		}
	}

	@Override
	public List<FrioCalorVO> getEquiposFrioCalor() {
		try {
			return frioCalorDao.getAllFrioCalorVO();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public List<FrioCalorVO> getEquiposFrioCalorByTipoAndEstado(String tipo,String estado) {
		try {
			return frioCalorDao.getFrioCalorByTipoAndEstado(tipo,estado);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
	}

	@Override
	public FrioCalorVO getFrioCalorByNumSerie(String numeroSerie) {
		try {
			return frioCalorDao.getFrioCalorByNumSerie(numeroSerie);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al Obtener un FRIOCALOR "+e.getMessage());
			return null;
		}
	}
	
	
	@Override
	public boolean verificarAltaModificacionFrioCalor(String numeroDeSerie) {
		// TODO Auto-generated method stub
		return false;
	}
	
	private FrioCalorVO getFrioCalorConMayuscula(FrioCalorVO fc){
		fc.setMarca(fc.getMarca().toUpperCase().trim());
		fc.setModelo(fc.getModelo().toUpperCase().trim());
		fc.setNumeroDeSerie(fc.getNumeroDeSerie().toUpperCase().trim());
		return fc;
	}
	
	@Override
	public List<FrioCalorVO> getFrioCalorDeAguaDeRed() {
		try {
			return frioCalorDao.getFrioCalorAguaDeRed();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
			// TODO: handle exception
		}
	}
	// --------------------- METODOS DE TIPO-PRODUCTO--------------------------
	@Override
	public String insertTipoProductoVO(TipoProductoVO tipoProducto) {
		tipoProducto.setNombre(tipoProducto.getNombre().toUpperCase());
		if(!nombreTipoProductoExistente(tipoProducto)){
			try {
				tipoProductoDao.insertTipoProductoVO(tipoProducto);
				return ConstantModel.SUCCESS;
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("Error al guardar un Tipo de Producto "+e.getMessage());
				return ConstantModel.FAILED;
			}
		}else {
			return ConstantModel.NOMBRE_DUPLICADO;
		}
	}
	
	/**
	 * Determina si el nombre ingresado en el objeto ya existe en la base de dato
	 * @param Tipo de Producto
	 * @return true si existe en la Base de Datos 
	 * Si no existe en la Base de Datos devuelve un false 
	 */
	private boolean nombreTipoProductoExistente(TipoProductoVO tp){
		boolean result;
		TipoProductoVO tipoProducto = tipoProductoDao.getTipoProductoByNombre(tp.getNombre());
		if(tp.getTipoProductoId() == null){
			//un control de alta
			if(tipoProducto !=null){
				result = true;
			}else {
				result = false;
			}
		}else {
			//control de update
			System.out.println("validando update de tipo de producto");
			if(tipoProducto != null){
				//existe un nombre en la BD
				if(tp.getTipoProductoId().equals(tipoProducto.getTipoProductoId())){
					result = false;
				}else{
					result = true;
				}
			}else{
				result = false;
			}
		}
		return result;
	}

	@Override
	public String deleteTipoProductoVO(TipoProductoVO tipoProducto){
		if(!existenProductosDelTipoProducto(tipoProducto)){
			try {
				tipoProductoDao.deleteTipoProductoVO(tipoProducto);
				return ConstantModel.SUCCESS;
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("Error al eliminar un Tipo de Producto "+e.getMessage());
				return ConstantModel.FAILED;
			}
		}else{
			return ConstantModel.DELETE_ASIGNADO;
		}
		
	}
	
	private boolean existenProductosDelTipoProducto(TipoProductoVO tp){
		if(productoDao.getProductosPorTipo(tp).isEmpty()){
			return false;
		}else return true;
	}

	@Override
	public String updateTipoProductoVO(TipoProductoVO tipoProducto) {
		tipoProducto.setNombre(tipoProducto.getNombre().toUpperCase());
		if(!nombreTipoProductoExistente(tipoProducto)){
			try {
				tipoProductoDao.updateTipoProductoVO(tipoProducto);
				return ConstantModel.SUCCESS;
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("Error al modificar un Tipo de Producto "+e.getMessage());
				return ConstantModel.FAILED;
			}
		}else{
			return ConstantModel.NOMBRE_DUPLICADO;
		}
	}

	
	@Override
	public TipoProductoVO getTipoProductoById(long tipoProductoId) {
		try{
			return tipoProductoDao.getTipoProductobyId(tipoProductoId);
		} catch (Exception e){
			e.printStackTrace();
			System.out.println("Error al Obtener un Tipo de Producto "+ e.getMessage());
			return null;
		}
	}
	

	@Override
	public List<ProductoVO> getProductosPorTipo(TipoProductoVO tipoProducto) {
		try{
			return productoDao.getProductosPorTipo(tipoProducto);
		}catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al listar productos por tipo");
			return null;
		}
	}

	@Override
	public List<ProductoVO> getProductos() {
		try {
			return productoDao.getAllProductoVO();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al listar producto");
			return null;
		}
	}

	@Override
	public List<TipoProductoVO> getTiposDeProductos() {
		try {
			return tipoProductoDao.getAllTipoDeProductoVO();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}


	//----------------- METODOS DE PACKS----------------------------------
	@Override
	public String insertPackVO(PackVO pack) {
		try {
			packDao.insertPackVO(pack);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al insertar un Pack "+e.getMessage());
			return ConstantModel.FAILED;
		}
		
	}

	@Override
	public String updatePackVO(PackVO pack) {
		try {
			packDao.updatePackVO(pack);
			return ConstantModel.SUCCESS;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al Modificar un Pack "+e.getMessage());
			return ConstantModel.FAILED;
		}
		
	}

	@Override
	public String deletePackVO(PackVO pack) {
		
		if(!existenComercializacionesPackDePack(pack)){
			try {
				packDao.deletePackVO(pack);
				return ConstantModel.SUCCESS;
			} catch (Exception e) {
				e.printStackTrace();
				System.out.println("Error al eliminar un Pack. "+e.getMessage());
				return ConstantModel.FAILED;
			}
		}else {
			return ConstantModel.DELETE_ASIGNADO;
		}	
	}
	
	private boolean existenComercializacionesPackDePack(PackVO p){
		if(comercializacionPackDao.getComercializacionPackByPack(p).isEmpty()){
			System.out.println(" NO HAY Pack asignados");
			return false;
			
		}else {
			System.out.println(" SI  HAY Pack asignados");
			return true;
		}
	}

	
	@Override
	public List<PackVO> getPacks() {
		try {
			return packDao.getAllPacks();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al eliminar un Pack "+e.getMessage());
			return null;
		}
	}

	@Override
	public PackVO getPackById(long packId) {
		try {
			return packDao.getPackById(packId);
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("Error al Obtener un Pack "+e.getMessage());
			return null;
		}
	}

	@Override
	public Boolean existeNombrePack(String nombre) {
		try{
			if (packDao.getPackByNombre(nombre) != null){
				return true;
			}else
				return false;
		}catch (Exception e){
			e.printStackTrace();
			System.out.println("Error al buscar nombre de Pack. "+e.getMessage());
			return null;	
		}
	}
	
	@Override
	public List<ProductoVO> getProductosConPrecio(long tipoClienteId) {
		try{
			TipoClienteVO tc = new TipoClienteVO();
			TipoClienteDao tipoClienteDao = new TipoClienteDaoImp();
			tc = tipoClienteDao.getTipoClienteById(tipoClienteId);
//			float porcentajeDescuento = tc.getPorcentajeDescuento() / 100;
			List <ProductoVO> listaProductos = getProductos();
			
			for (int i = 0; i < listaProductos.size(); ++i){
					ProductoVO pVO = new ProductoVO();
					pVO = listaProductos.get(i);
//					pVO.setPrecio(pVO.getPrecio() - (porcentajeDescuento * pVO.getPrecio()));
	//				pVO.setPrecio( Math.rint(pVO.getPrecio() * 8)/ 8);
					listaProductos.set(i, pVO);
			}
			return listaProductos;
		}catch (Exception e){
			e.printStackTrace();
			System.out.println("Error la Obtener el listado de Poductos con el Precio  "+e.getMessage());
			return null;
		}
	}

	@Override
	public List<FrioCalorVO> buscarFrioCalorPorParametro(FrioCalorVO frioCalor) {
		List<FrioCalorVO> result;
		try {
			result = frioCalorDao.searchFrioCalor(frioCalor);
		} catch (Exception e) {
			e.printStackTrace();
			result = null;
		}
		return result;
	}

	@Override
	public List<FrioCalorVO> getEquiposFrioCalorByFrioCalorTipoEstado(
			FrioCalorVO frioCalor, String tipo, String estado) {
		try {
			return frioCalorDao.getEquiposFrioCalorByFrioCalor(frioCalor, tipo, estado);
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

}


